#!/usr/bin/env python2

import os
import sys
import socket
import time
import subprocess
import fcntl
import types
import errno
import getopt

from config import Config
from storage import Storage
from utils import Exp
from localfs import LocalFs

class ChunkBalance():
    def __init__(self, config, home, name):
        self.config = config
        self.home = home
        self.name = name
        self.storage = Storage(self.config)
        localfs = LocalFs(home)
        self.list = localfs.build_chunk_list("object")['object']

    def balance(self, t):
        heads = []
        fail = 0
        #print (self.list)
        for i in self.list:
            oid = os.path.basename(i)
            try:
                self.storage.balance(oid)
            except Exp, e:
                if (e.errno == errno.ENOENT):
                    pass
                else:
                    raise

    def __bynode(self, path):
        #print ("move %s" % (path))

        try:
            chkid = self.storage.chkid(path)
        except Exp, e:
            if (e.errno == errno.ENOENT):
                return 0
            else:
                raise

        location = self.storage.location(chkid, 3)
        local = self.name

        if (location[0] != local):
            return 0

        conn = self.storage.connection(chkid)
        if ((len(conn) != 0) and (local not in conn.keys())):
            return 0

        loc = ""
        for i in location:
            loc = loc + i + ','

        loc = loc[:-1]

        #print ("location %s, local %s" % (location, local))
        return self.storage.move_object(chkid, loc, True)

    def __byrack(self, path):
        #print ("move %s" % (path))

        try:
            chkid = self.storage.chkid(path)
        except Exp, e:
            if (e.errno == errno.ENOENT):
                return 0
            else:
                raise

        location = self.storage.location(chkid, 3)
        local = self.name

        #print ("location %s --> %s" % (location[0], local))
        if (location[0] != local):
            return 0

        loc = ""
        for i in location:
            loc = loc + i + ','

        loc = loc[:-1]

        #print ("location %s, local %s" % (location, local))
        return self.storage.move_object(chkid, loc, True)
        
def usage():
    print ("usage:")
    print (sys.argv[0] + " --balance <disk num>")
    #print (sys.argv[0])

def main():
    try:
        opts, args = getopt.getopt(
                sys.argv[1:], 
                'h', ['balance=', 'help']
                )
    except getopt.GetoptError, err:
        print str(err)
        usage()

    if (len(sys.argv) == 1):
        usage()
        exit(0)

    config = Config()
    for o, a in opts:
        if o in ('--help'):
            usage()
            exit(0)
        elif o == '--balance':
            from instence import Instence
            instence = Instence(config, a)
            chunkbalance = ChunkBalance(config, instence.home, instence.name)
            chunkbalance.balance('rack')
        else:
            assert False, 'oops, unhandled option: %s, -h for help' % o
            exit(1)

if __name__ == '__main__':
    main()
